package com.veetao.api.service.impl;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import javax.annotation.Resource;

import org.springframework.beans.factory.InitializingBean;
import org.springframework.stereotype.Service;

import com.veetao.api.dao.impl.UserActionManageDao;
import com.veetao.api.model.UserAction;
import com.veetao.api.model.UserActionPermission;
import com.veetao.api.utils.McpUtils;

/**
 * 
 * @author guohongtao
 * @date 2016年10月20日
 */
@Service
public class UserActionManageService implements InitializingBean {

	private Map<Integer, List<UserActionPermission>> allowPermission;
	private Map<Integer, List<UserActionPermission>> forbidPermission;
	private Map<Integer, UserAction> userActions;
	
	@Resource
	private UserActionManageDao actionManageDao;

	@Override
	public void afterPropertiesSet() throws Exception {
		refreshAllUserPermission();
	}
	
	public void refreshAllUserPermission() {
		List<UserAction> allUserActions = actionManageDao.queryAllUserActions();
		Map<Integer, UserAction> newUserActions = new HashMap<Integer, UserAction>();
		for(UserAction action : allUserActions) {
			newUserActions.put(action.getId(), action);
		}
		
		Map<Integer, List<UserActionPermission>> newAllowPermissions = new HashMap<Integer, List<UserActionPermission>>();
		Map<Integer, List<UserActionPermission>> newForbidPermissions = new HashMap<Integer, List<UserActionPermission>>();
		List<UserActionPermission> list = actionManageDao.queryAllUserActionPermission();
		for(UserActionPermission p : list) {
			int userId = p.getUserId();
			if(p.isForbidPermission()) {
				appendNewPermissionForUser(userId,newForbidPermissions, p);
				continue;
			} else if(p.isAllowPermission()) {
				appendNewPermissionForUser(userId, newAllowPermissions, p);
			}
			
		}
		
		
		userActions = newUserActions;
		allowPermission = newAllowPermissions;
		forbidPermission = newForbidPermissions;
		
	}
	
	
	public void refreshUserActions() {
		List<UserAction> allUserActions = actionManageDao.queryAllUserActions();
		Map<Integer, UserAction> newUserActions = new HashMap<Integer, UserAction>();
		for(UserAction action : allUserActions) {
			newUserActions.put(action.getId(), action);
		}
		
		userActions = newUserActions;
	}
	
	public void refreshUserPermission(int userId) {
		List<UserActionPermission> newAllowPermissions = new ArrayList<UserActionPermission>();
		List<UserActionPermission> newForbidPermissions = new ArrayList<UserActionPermission>();
		List<UserActionPermission> list = actionManageDao.queryAllPermissionForUser(userId);
		for(UserActionPermission p : list) {
			if(p.isForbidPermission()) {
				newForbidPermissions.add(p);
			} else if(p.isAllowPermission()) {
				newAllowPermissions.add(p);
			}
		}
		
		
		allowPermission.put(userId, newAllowPermissions);
		forbidPermission.put(userId,newForbidPermissions);
		
	}

	/**
	 * @param userId
	 * @param newForbidPermissions
	 * @author guohongtao
	 */
	private void appendNewPermissionForUser(int userId,
			Map<Integer, List<UserActionPermission>> userPermissions, UserActionPermission p) {
		if(userPermissions.containsKey(userId)) {
			userPermissions.get(userId).add(p);
		} else {
			userPermissions.put(userId, new ArrayList<UserActionPermission>());
			userPermissions.get(userId).add(p);
		}
	}

	public UserActionManageService() {
		super();
	}

	/**
	 * @param userId
	 * @param methodName
	 * @return
	 * @author guohongtao
	 */
	public UserAction getUserForbidAction(int userId, String actionName) {
		if(actionAllowed(userId,actionName)) {
			return null;
		}
		
		return getForbidAction(userId,actionName);
	}

	/**
	 * @param userId
	 * @param actionName
	 * @return
	 * @author guohongtao
	 */
	private boolean actionAllowed(int userId, String actionName) {
		List<UserActionPermission> allowPermissions = allowPermission.get(userId);
		if(allowPermissions == null) {
			return false;
		}
		
		for(UserActionPermission p : allowPermissions) {
			if(p.isValid() && actionMatches(p.getActionId(),actionName)) {
				return true;
			}
		}
		
		return false;
	}
	
	
	public List<UserActionPermission> getUserActionPermissions(int userId) {
		List<UserActionPermission> list = new ArrayList<UserActionPermission>();
		List<UserActionPermission> allowPermissions = allowPermission.get(userId);
		if(allowPermissions != null) {
			list.addAll(allowPermissions);
		}
		
		List<UserActionPermission> forbidPermissions = forbidPermission.get(userId);
		if(forbidPermissions != null) {
			list.addAll(forbidPermissions);
		}
		
		return list;
	}

	/**
	 * @param actionId
	 * @param actionName
	 * @return
	 * @author guohongtao
	 */
	private boolean actionMatches(int actionId, String actionName) {
		if(userActions == null) {
			return false;
		}
		UserAction userAction = userActions.get(actionId);
		if(userAction == null) {
			return false;
		}
		
		return McpUtils.leftMatch(actionName, userAction.getName());
	}

	/**
	 * @param userId
	 * @param actionName
	 * @return
	 * @author guohongtao
	 */
	private UserAction getForbidAction(int userId, String actionName) {
		List<UserActionPermission> forbidPermissions = forbidPermission.get(userId);
		if(forbidPermissions == null) {
			return null;
		}
		for(UserActionPermission p : forbidPermissions) {
			if(p.isValid() && actionMatches(p.getActionId(),actionName)) {
				return getUserAction(p.getActionId());
			}
		}
		return null;
	}

	/**
	 * @param actionId
	 * @return
	 * @author guohongtao
	 */
	private UserAction getUserAction(int actionId) {
		if(userActions == null) {
			return null;
		}
		return userActions.get(actionId);
	}

	public UserActionManageDao getActionManageDao() {
		return actionManageDao;
	}

	public void setActionManageDao(UserActionManageDao actionManageDao) {
		this.actionManageDao = actionManageDao;
	}


}
